// /utils/aliyunToken.js

import CryptoJS from 'crypto-js';

/**
 * 对文本进行 URL 编码，以符合阿里云的要求
 * @param {string} text 需要编码的文本
 * @returns {string} 编码后的文本
 */
function _encodeText(text) {
	return encodeURIComponent(text)
		.replace(/\+/g, '%20')
		.replace(/\*/g, '%2A')
		.replace(/%7E/g, '~')
		.replace(/%21/g, '!')
		.replace(/%27/g, "'")
		.replace(/%28/g, '(')
		.replace(/%29/g, ')');
}

/**
 * 对字典进行排序并编码成 URL 查询字符串
 * @param {object} dict 需要处理的字典
 * @returns {string} 编码后的查询字符串
 */
function _encodeDict(dict) {
	const sortedKeys = Object.keys(dict).sort();
	const parts = [];
	for (const key of sortedKeys) {
		parts.push(`${_encodeText(key)}=${_encodeText(dict[key])}`);
	}
	return parts.join('&');
}

/**
 * 生成符合 ISO 8601 格式的当前 UTC 时间字符串
 * @returns {string} 格式化的时间字符串，如 "2023-10-27T08:05:30Z"
 */
function _getCurrentUTCTimeString() {
	const date = new Date();
	return date.toISOString().slice(0, 19) + 'Z';
}

/**
 * 生成 UUID v4
 * @returns {string} UUID 字符串
 */
function _generateUUID() {
	if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
		return crypto.randomUUID();
	}
	return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
		const r = Math.random() * 16 | 0;
		const v = c === 'x' ? r : (r & 0x3 | 0x8);
		return v.toString(16);
	});
}

/**
 * 从阿里云获取 Token
 * @param {string} accessKeyId - 你的阿里云 AccessKeyId
 * @param {string} accessKeySecret - 你的阿里云 AccessKeySecret
 * @returns {Promise<{token: string, expireTime: number, expireTimeString: string}|null>} 
 *          返回一个 Promise，resolve 的值为包含 token、过期时间戳和格式化时间的对象，失败则 resolve null。
 */
export function getAliyunToken(accessKeyId = "LTAI5tPVmwkhNYL5W6ZX2ZiC", accessKeySecret =
	"4jeiZceHKgZeERbFY6eM2sMBm77W4f") {
	return new Promise((resolve, reject) => {
		if (!accessKeyId || !accessKeySecret) {
			console.error('AccessKeyId 和 AccessKeySecret 不能为空');
			reject(new Error('AccessKeyId 和 AccessKeySecret 不能为空'));
			return;
		}

		const parameters = {
			AccessKeyId: accessKeyId,
			Action: 'CreateToken',
			Format: 'JSON',
			RegionId: 'cn-shanghai',
			SignatureMethod: 'HMAC-SHA1',
			SignatureNonce: _generateUUID(),
			SignatureVersion: '1.0',
			Timestamp: _getCurrentUTCTimeString(),
			Version: '2019-02-28'
		};

		try {
			const queryString = _encodeDict(parameters);
			const stringToSign = `GET&${_encodeText('/')}&${_encodeText(queryString)}`;

			const hmacSha1 = CryptoJS.HmacSHA1(stringToSign, accessKeySecret + '&');
			const signature = CryptoJS.enc.Base64.stringify(hmacSha1);
			const encodedSignature = _encodeText(signature);

			const fullUrl =
				`https://nls-meta.cn-shanghai.aliyuncs.com/?Signature=${encodedSignature}&${queryString}`;

			uni.request({
				url: fullUrl,
				method: 'GET',
				success: (response) => {
					if (response.statusCode === 200) {
						const rootObj = response.data;
						if (rootObj.Token && rootObj.Token.Id) {
							const token = rootObj.Token.Id;
							const expireTime = rootObj.Token.ExpireTime;
							const expireDate = new Date(expireTime * 1000);
							const expireTimeString = expireDate.toLocaleString();
							resolve({
								token: token,
								expireTime: expireTime,
								expireTimeString: expireTimeString
							});
						} else {
							const errorMsg = rootObj.Message || '获取 Token 失败，返回数据格式不正确';
							console.error('获取阿里云 Token 失败:', errorMsg);
							reject(new Error(errorMsg));
						}
					} else {
						const errorMsg = `HTTP 请求失败，状态码: ${response.statusCode}`;
						console.error(errorMsg);
						reject(new Error(errorMsg));
					}
				},
				fail: (err) => {
					console.error('网络请求出错:', err);
					reject(err);
				}
			});
		} catch (e) {
			console.error('生成请求参数或签名时出错:', e);
			reject(e);
		}
	});
}